
#include "copyright.h"
#include "synch.h"
#include "system.h"
#include <iostream>

Thread *foodClerkThreads[5];


Lock *foodClerkLineLock;
Condition *foodClerkLineConditionVariables[5];

Lock *foodClerkLocks[5];
Condition *foodClerkConditionVariables[5];

/*int foodClerkLineLock;
int foodClerkLineConditionVariables[5];
int foodClerkLocks[5];
int foodClerkConditionVariables[5];*/

int foodClerkLineCount[5];
int foodEarnings[5];
enum ClerkStateEnum foodClerkStates[5];

int popcornBeingSold[5];
int sodaBeingSold[5];
int foodTotal[5];

void FoodClerk(int clerkNumber)
{
	while(true)
	{
onBreak:

		
		foodClerkLineLock->Acquire();		//Lock the lines
		foodClerkLocks[clerkNumber]->Acquire();
		
		/*LockAcquire(foodClerkLineLock);
		LockAcquire(foodClerkLocks[clerkNumber]);*/
		if(foodClerkStates[clerkNumber]==on_break)
		{
			printf("%s %i going on break\n",currentThread->getName(),clerkNumber);
		}
		/*for(int i=0;foodClerkStates[clerkNumber]==on_break;i++)
		{
			currentThread->Yield();
			if(i==BREAK_LENGTH)
			{
				printf("%s %i coming off of break\n",currentThread->getName(),clerkNumber);
				foodClerkStates[clerkNumber]=available;
			}
		}*/
		if(foodClerkStates[clerkNumber]!=on_break)
		{
			
			if(foodClerkLineCount[clerkNumber]>0)	//If there is a line
			{
				printf("%s %i has a line length %i and is signaling a customer\n",currentThread->getName(),clerkNumber,foodClerkLineCount[clerkNumber]);
				
				foodClerkLineConditionVariables[clerkNumber]->Signal(foodClerkLineLock);	//Wake up the first person in line
				
				/*CVSignal(foodClerkLineConditionVariables[clerkNumber],foodClerkLineLock);*/
				foodClerkLineCount[clerkNumber]--;	//decrease the line size
				foodClerkStates[clerkNumber]=busy;	//make myself busy
			}
			else					//If there isn't a line
			{
				printf("%s %i has no line. I am available for a customer\n",currentThread->getName(),clerkNumber);
				foodClerkStates[clerkNumber]=available;	//Set myself available
			}
			
			foodClerkLineLock->Release();		//release the line lock
			
			/*LockRelease(foodClerkLineLock);*/
		}
		
		foodClerkConditionVariables[clerkNumber]->Wait(foodClerkLocks[clerkNumber]);	//Wait for a customer to signal  
		
		/*CVWait(foodClerkConditionVariables[clerkNumber], foodClerkLocks[clerkNumber]);*/
		if(foodClerkStates[clerkNumber]==on_break)
		{
			goto onBreak;
		}

		
		foodClerkConditionVariables[clerkNumber]->Signal(foodClerkLocks[clerkNumber]);	//Acknowledge Order
		foodClerkConditionVariables[clerkNumber]->Wait(foodClerkLocks[clerkNumber]);	//Wait for more
		
		/*CVSignal(foodClerkConditionVariables[clerkNumber],foodClerkLocks[clerkNumber]);
		CVSWait(foodClerkConditionVariables[clerkNumber],foodClerkLocks[clerkNumber]);*/

		
		
		foodClerkLocks[clerkNumber]->Acquire();
		
		/*LockAcquire(foodClerkLocks[clerkNumber]);*/
		foodTotal[clerkNumber]=popcornBeingSold[clerkNumber]*5+sodaBeingSold[clerkNumber]*4;	//calculate total
		
		printf("%s %i has an order for %i popcorn and %i soda. The cost is %i.\n",currentThread->getName(),clerkNumber,popcornBeingSold[clerkNumber],sodaBeingSold[clerkNumber],foodTotal[clerkNumber]);
		
		foodClerkConditionVariables[clerkNumber]->Signal(foodClerkLocks[clerkNumber]);	//Give Order
		foodClerkConditionVariables[clerkNumber]->Wait(foodClerkLocks[clerkNumber]);	//Wait for payment
		
		/*CVSignal(foodClerkConditionVariables[clerkNumber],foodClerkLocks[clerkNumber]);
		CVSWait(foodClerkConditionVariables[clerkNumber],foodClerkLocks[clerkNumber]);*/
		
		printf("%s %i has been paid for the order\n",currentThread->getName(),clerkNumber);
		
		foodClerkConditionVariables[clerkNumber]->Signal(foodClerkLocks[clerkNumber]);	
		
		/*CVSignal(foodClerkConditionVariables[clerkNumber],foodClerkLocks[clerkNumber]);*/

	}
}
